home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d16 / tprint.arc / PDEVICE.PAS < prev    next >
Pascal/Delphi Source File  |  1991-04-10  |  9KB  |  287 lines

  1. {$V-}
  2. UNIT pDevice;
  3. INTERFACE
  4. USES WObjects,WinTypes,WinProcs,Strings,WinDos;
  5. Type
  6.   devArray = array[0..64] of Char;    {holds results of params call}
  7.   pPrnDevice = ^tPrnDevice;
  8.   tprnDevice = object(tObject)
  9.     hPrintDC:  hDC;                  {print device context}
  10.     hWindow:   hWnd;                 {parent window}
  11.     docName:   pChar;                 {name of the document}
  12.     device:    devArray;             {device name from windows}
  13.     driver:    devArray;             {driver name from windows}
  14.     dMode:     tDevMode;             {device mode record}
  15.     noSpooler: Boolean;              {if spooler is operating}
  16.     outPort:   devArray;             {printer port}
  17.     okPrint:   boolean;                 {flag}
  18.  
  19.     CONSTRUCTOR Init;
  20.     Function DeleteContext: Boolean;
  21.     Procedure prnDeviceMode(wnd: hWnd);
  22.     Function GetPrinterParms: Boolean;
  23.     Function DCCreated: Boolean;
  24.     Function beginDoc: Boolean;
  25.     Function endDocument: Boolean;
  26.     Function doNewFrame: Boolean; virtual;
  27.   End;
  28.  
  29.   {-- These are types used to call the device mode dialog from a printer
  30.       driver.  They are used in the tPrnDevice.prnDeviceMode function.
  31.       tGetDevMode is used for drivers not written for windows 3.  The
  32.       ExtDevMode is for windows 3 printer drivers --}
  33.  
  34.   tGetDevMode = function(hWindow: hWnd; dHan: tHandle; devName,output: pChar): Boolean;
  35.   tGetExtDevMode = function(hWIndow: hWnd;
  36.                             dHan: tHandle;
  37.                             outMode: tDevMode;
  38.                             devName: pChar;
  39.                             outPut: pChar;
  40.                             inMode: tDevMode;
  41.                             profile: pChar;
  42.                             pMode: word): Boolean;
  43.   tMode= tDeviceMode;
  44.  
  45.   pPrinter = ^tPrinter;
  46.   tPrinter = object(tprnDevice)
  47.     maxX:  word;                {max width of page}
  48.     maxY:  Word;                {max height of page}
  49.     posX:        Word;            {current column}
  50.     posY:         Word;            {current row}
  51.     metrics: TTextMetric;        {text metric information}
  52.  
  53.     constructor Init;
  54.     FUNCTION Start(dName: pChar;hw: hWnd): Boolean;
  55.     Function CheckStart: Boolean;
  56.     Function newAbortProc: Boolean;
  57.     Function textLine(aStr: pChar): Boolean;
  58.     Function Finish: Boolean;
  59.     Function pageSize(var ps: tPoint): Boolean;
  60.     Function height: word;
  61.     Function endLine: Boolean;
  62.     Function checkNewPage: Boolean;
  63.     Function newPage: Boolean;
  64.     Function resetPos: Boolean;
  65.     Function doNewFrame: Boolean;virtual;
  66.   End;
  67.  
  68. IMPLEMENTATION
  69.  
  70. CONSTRUCTOR tPrnDevice.Init;
  71. Begin
  72.   tObject.Init;
  73. End;
  74.  
  75. Function tPrnDevice.deleteContext;
  76. {-- Delete the device context for the printer --}
  77. begin
  78.   deleteDC(hPrintDC);
  79. End;
  80.  
  81. Procedure tPrnDevice.prnDeviceMode;
  82. {-- Displays the printer driver dialog box to allow the user to change
  83.     default print parameters.  If the driver is for window 3, this call
  84.     will only affect the current application.  Other drivers will affect
  85.     all applications.  --}
  86.  var
  87.   dHandle: tHandle;     {handle of the load library for the current printer}
  88.   drvName: pChar;       {name of the driver used to get dHandle}
  89.   pAddr:   tFarProc;    {address of the function in the DLL we want to EXEC}
  90.  
  91.  
  92. Begin
  93.   if getPrinterParms then begin            {retrieve printer info from windows}
  94.     drvName := driver;
  95.     strCat(drvName,'.drv');             {make a file name out of the driver}
  96.     dHandle := LoadLibrary(drvName);    {load the DLL for the printer}
  97.   {-- the next instruction requests the address of a procedure called
  98.       ExtDeviceMode from the DLL. Drivers written for windows 3 should
  99.       contain this procedure.  if successful, that address is typecast
  100.       to the tGetExtDevMode function type, and executed. --}
  101.  
  102.     pAddr := getProcAddress(dHandle,'ExtDeviceMode');
  103.     if (pAddr <> nil) then begin
  104.       tGetExtDevMode(pAddr)(wnd,dHandle,dMode,drvName,outPort,dMode,nil,dm_prompt OR dm_copy);
  105.     end else begin
  106.   {-- If the drivers is not written for windows 3, or there is no extDeviceMode
  107.       procedure, the standard device mode function is called --}
  108.  
  109.       pAddr := GetProcAddress(dHandle,'DEVICEMODE');
  110.       if (pAddr <> nil) then begin
  111.         tGetDevMode(pAddr)(wnd,dHandle,drvName,outPort);
  112.       End;
  113.     End;
  114.     FreeLibrary(dHandle);   {the library is freed when we are done with it}
  115.   End;
  116. end;
  117.  
  118. Function tPrnDevice.GetPrinterParms;
  119. {-- This function retrieves the printer parameters from the WIN.INI file --}
  120. var
  121.   astr: array[0..255] of char;
  122.   result: Integer;
  123.   cPtr: pChar;
  124.   cPos: pChar;
  125.  
  126. Begin
  127.   result := GetProfileString('windows','device',nil,astr,sizeOF(astr));
  128.   cPtr := aStr;
  129.   cPos := strScan(cPtr,',');
  130.   strLcopy(device,cPtr,(cPos - cPtr));
  131.   cPtr := cPos + 1;
  132.   cPos := strScan(cPtr,',');
  133.   strLcopy(driver,cPtr,(cPos - cptr));
  134.   cPtr := cPos + 1;
  135.   strLcopy(outPort,cPtr,strLen(cPtr));
  136.   result := GetProfileString('windows','spooler',nil,astr,sizeOf(aStr));
  137.   noSpooler := (strPas(aStr) = 'no');
  138. End;
  139.  
  140. FUNCTION tPrnDevice.DCcreated;
  141. {-- Creates the device context for the printer --}
  142. Begin
  143.   hPrintDC := CreateDC(driver,device,outPort,nil);
  144.   DCCreated := (hPrintDC > 0);
  145. End;
  146.  
  147. Function tPrnDevice.beginDoc: Boolean;
  148. {-- sends the startdoc escape sequence to windows --}
  149. Begin
  150.   beginDoc := (escape(hPrintDC,startDoc,sizeOf(docName),docName,nil) > 0);
  151. end;
  152.  
  153. Function tPrnDevice.EndDocument: Boolean;
  154. {-- Ends the document.  Closes the print manager, if used, and sends output
  155.     to the printer --}
  156. Begin
  157.   doNewFrame;
  158.   escape(hPrintDC,EndDoc,0,nil,nil);
  159. End;
  160.  
  161. Function tPrnDevice.doNewFrame: Boolean;
  162. {-- sends the newFrame escape code to windows. In the case of a printer,
  163.     this results in a form feed --}
  164.  
  165. Begin
  166.   doNewFrame := (escape(hPrintDC,NewFrame,0,nil,nil) > 0);
  167. End;
  168.  
  169. (***********************************************************)
  170. Constructor tPrinter.Init;
  171. Begin
  172.   tPrnDevice.Init;
  173. End;
  174.  
  175. Function tPrinter.Start;
  176. {-- after initialization, this method sets the printer up to print --}
  177. var
  178.   ap: tPoint;
  179.  
  180. Begin
  181.   hWindow := Hw;            {save the parent window. Seemed like a good idea}
  182.   hPrintDC := 0;            {init the device context to 0}
  183.   GlobalCompact(0);            {compacts global memory}
  184. {-- the next line retrieves the printer parms from WIN.INI, and creates
  185.     the device context --}
  186.   if (getPrinterParms and DCcreated) then begin
  187.     docName := dName;
  188. {-- The next few lines deal with the physical fonts.  GetTextMetrics
  189.     retrieves the information for the printer.  Page size returns a tPoint
  190.     record with the X and Y values for the DeviceCaps page heigth and width.
  191.     maxX and maxY are then set at one less that these values --}
  192.  
  193.     getTextMetrics(hPrintDC,Metrics);
  194.     pageSize(ap);
  195.     maxX := ap.x-1;
  196.     maxY := ap.y-1;
  197.     start := CheckStart;
  198.   end
  199.   else
  200.     start := false;
  201. End;
  202.  
  203. Function tPrinter.CheckStart;
  204. {-- This function will eventually set up a printer abort proc. Now, it
  205.     only calls the beginDoc function  --}
  206. Begin
  207.   okPrint := true;
  208.   newAbortProc;
  209.   okPrint := BeginDoc;
  210.   CheckStart := okPrint;
  211. End;
  212.  
  213. Function tPrinter.NewAbortProc;
  214. begin
  215. end;
  216.  
  217. Function tPrinter.textLine(aStr: pChar): Boolean;
  218. {-- sends a line of text to the printer, starting at the X and Y
  219.     co-ordinates.  End line adjusts the row based on the height of
  220.     the font from the textMetrics record  --}
  221. Begin
  222.   if OkPrint then begin
  223.     if TextOut(hPrintDC,posX,posY,aStr,strLen(aStr)) then
  224.       endLine;
  225.   End;
  226. end;
  227.  
  228. Function tPrinter.Finish;
  229. {-- Ends the print job --}
  230. Begin
  231.   EndDocument;
  232.   deleteContext;
  233. End;
  234.  
  235. Function tPrinter.PageSize(var ps: tPoint): Boolean;
  236. {-- Calls the device caps function to get the size of the page --}
  237. Begin
  238.   ps.X := GetDeviceCaps(hPrintDC,HorzRes);
  239.   ps.Y := GetDeviceCaps(hPrintDC,VertRes);
  240. end;
  241.  
  242. Function tPrinter.height: word;
  243. {-- returns the height of the font. If your line spacing
  244.     is to tight, you can return a different value, and
  245.     increase it.   --}
  246. Begin
  247.   height := metrics.tmHeight;
  248. End;
  249.  
  250. Function tPrinter.EndLine: Boolean;
  251. {-- causes a 'line feed' by incrementing the row by the height of the font --}
  252. Begin
  253.   posX := 0;
  254.   posY := posY + height;
  255.   checkNewPage;
  256. End;
  257.  
  258. Function tPrinter.CheckNewPage: Boolean;
  259. {-- compares the row with the page height to see if a new page is required --}
  260. Begin
  261.   if (posY > maxY) then
  262.     newPage;
  263. End;
  264.  
  265. Function tPrinter.NewPage: boolean;
  266. {-- Causes a form feed to be sent to the printer --}
  267. Begin
  268.   resetPos;
  269.   doNewFrame;
  270. End;
  271.  
  272. Function tPrinter.ResetPos: Boolean;
  273. {-- resets the row and column to zero --}
  274. Begin
  275.   posX := 0;
  276.   posY := 0;
  277. End;
  278.  
  279. Function tPrinter.doNewFrame: Boolean;
  280. {-- this function will do more when this unit is finished. Right now,
  281.     it calls the ancestor new frame method to cause a line feed. --}
  282. Begin
  283.   if OkPrint then
  284.     doNewFrame := tPrnDevice.doNewFrame;
  285. End;
  286.  
  287. end.